package com.jijs.framework.service;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jijs.framework.CodeConstant;
import com.jijs.framework.dao.BaseDaoI;
import com.jijs.framework.model.EasyUIComboTree;
import com.jijs.framework.model.EasyUIDataGrid;
import com.jijs.framework.model.PageHelper;
import com.jijs.framework.model.pmodel.AdeUser;
import com.jijs.framework.model.tmodel.TadeModule;
import com.jijs.framework.model.tmodel.TadeOrganization;
import com.jijs.framework.model.tmodel.TadeRole;
import com.jijs.framework.model.tmodel.TadeUser;
import com.jijs.framework.util.ChineseCharToEn;
import com.jijs.framework.util.ExcelUtil;
import com.jijs.framework.util.MD5Util;
import com.jijs.framework.util.StringUtil;

/**
 * 用户管理服务类
 * 
 * @author jijs
 *
 */
@Service
public class UserManagerService {

	@Autowired
	private BaseDaoI<TadeUser> userDao;

	@Autowired
	private BaseDaoI<TadeRole> roleDao;

	@Autowired
	private BaseDaoI<TadeModule> moduleDao;

	@Autowired
	private BaseDaoI<TadeOrganization> organizationDao;

	public AdeUser login(AdeUser user) {

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("loginName", user.getLoginName());
		params.put("password", MD5Util.md5(user.getPassword()));
		TadeUser t = userDao.get("from TadeUser t where t.loginName = :loginName and t.password = :password", params);
		if (t != null) {
			BeanUtils.copyProperties(t, user);
			if (t.getTadeRoles() != null && !t.getTadeRoles().isEmpty()) {
				String roleIds = "";
				String roleNames = "";
				boolean b = false;
				for (TadeRole role : t.getTadeRoles()) {
					if (b) {
						roleIds += ",";
						roleNames += ",";
					} else {
						b = true;
					}
					roleIds += role.getId();
					roleNames += role.getRoleName();
				}
				user.setRoleIds(roleIds);
				user.setRoleNames(roleNames);
			}
			return user;
		}
		return null;
	}

	public AdeUser loginByLoginName(String loginName) {
		AdeUser user = new AdeUser();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("loginName", loginName);
		TadeUser t = userDao.get("from TadeUser t where t.loginName = :loginName", params);
		if (t != null) {
			BeanUtils.copyProperties(t, user);
			if (t.getTadeRoles() != null && !t.getTadeRoles().isEmpty()) {
				String roleIds = "";
				String roleNames = "";
				boolean b = false;
				for (TadeRole role : t.getTadeRoles()) {
					if (b) {
						roleIds += ",";
						roleNames += ",";
					} else {
						b = true;
					}
					roleIds += role.getId();
					roleNames += role.getRoleName();
				}
				user.setRoleIds(roleIds);
				user.setRoleNames(roleNames);
			}
			return user;
		}
		return null;
	}

	synchronized public void reg(AdeUser user) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("loginName", user.getLoginName());
		if (userDao.count("select count(*) from TadeUser t where t.loginName = :loginName", params) > 0) {
			throw new Exception("登录名已存在！");
		} else {
			TadeUser u = new TadeUser();
			BeanUtils.copyProperties(user, u);
			u.setId(StringUtil.generateUUID());
			u.setLoginName(user.getLoginName());
			u.setPassword(MD5Util.md5(user.getPassword()));
			u.setUserState(CodeConstant.STATE_NORMAL);
			u.setNameLetter(ChineseCharToEn.getFristLetter(u.getUserName()));
			u.setCreateDate(new Date());

			userDao.save(u);
		}
	}

	public EasyUIDataGrid dataGrid(AdeUser user, PageHelper ph) {
		EasyUIDataGrid dg = new EasyUIDataGrid();
		List<AdeUser> ul = new ArrayList<AdeUser>();
		Map<String, Object> params = new HashMap<String, Object>();

		String hql = " from TadeUser t ";
		List<TadeUser> l = userDao.find(hql + whereHql(user, params) + orderHql(ph), params, ph.getPage(),
				ph.getRows());
		if (l != null && l.size() > 0) {
			for (TadeUser t : l) {
				AdeUser u = new AdeUser();
				BeanUtils.copyProperties(t, u);
				if (t.getTadeOrganization() != null && StringUtils.isNotBlank(t.getTadeOrganization().getOrgName())) {
					u.setOrganizationName(t.getTadeOrganization().getOrgName());
				}

				Set<TadeRole> roles = t.getTadeRoles();
				if (roles != null && !roles.isEmpty()) {
					String roleIds = "";
					String roleNames = "";
					boolean b = false;
					for (TadeRole tr : roles) {
						if (b) {
							roleIds += ",";
							roleNames += ",";
						} else {
							b = true;
						}
						roleIds += tr.getId();
						roleNames += tr.getRoleName();
					}
					u.setRoleIds(roleIds);
					u.setRoleNames(roleNames);
				}
				ul.add(u);
			}
		}
		dg.setRows(ul);
		dg.setTotal(userDao.count("select count(*) " + hql + whereHql(user, params), params));
		return dg;
	}

	private String whereHql(AdeUser user, Map<String, Object> params) {
		String hql = "";
		if (user != null) {
			hql += " where 1=1 ";
			if (StringUtils.isNotEmpty(user.getLoginName())) {
				hql += " and t.loginName like :loginName";
				params.put("loginName", "%%" + user.getLoginName() + "%%");
			}
			if (StringUtils.isNotEmpty(user.getUserName())) {
				hql += " and t.userName like :userName";
				params.put("userName", "%%" + user.getUserName() + "%%");
			}
			if (StringUtils.isNotEmpty(user.getUserState())) {
				hql += " and t.userState = :userState";
				params.put("userState", user.getUserState());
			}
			if (user.getCreateDateStart() != null) {
				hql += " and t.createDate >= :createDateStart";
				params.put("createDateStart", user.getCreateDateStart());
			}
			if (user.getCreateDateEnd() != null) {
				hql += " and t.createDate <= :createDateEnd";
				params.put("createDateEnd", user.getCreateDateEnd());
			}
			if (user.getUpdateDateStart() != null) {
				hql += " and t.updateDate >= :updateDateStart";
				params.put("updateDateStart", user.getUpdateDateStart());
			}
			if (user.getUpdateDateEnd() != null) {
				hql += " and t.updateDate <= :updateDateEnd";
				params.put("updateDateEnd", user.getUpdateDateEnd());
			}
		}
		return hql;
	}

	private String orderHql(PageHelper ph) {

		String orderString = " order by t.userState asc";
		if (ph.getSort() != null && ph.getOrder() != null) {
			orderString += " ,t." + ph.getSort() + " " + ph.getOrder();
		}
		return orderString;
	}

	synchronized public void add(AdeUser user) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("loginName", user.getLoginName());
		if (userDao.count("select count(*) from TadeUser t where t.loginName = :loginName", params) > 0) {
			throw new Exception("登录名已存在！");
		} else {
			TadeUser u = new TadeUser();
			BeanUtils.copyProperties(user, u);
			u.setId(StringUtil.generateUUID());
			u.setCreateDate(new Date());
			u.setPassword(MD5Util.md5(user.getPassword()));
			u.setUserState(CodeConstant.STATE_NORMAL);
			u.setNameLetter(ChineseCharToEn.getFristLetter(u.getUserName()));
			u.setTadeOrganization(organizationDao.get(TadeOrganization.class, user.getOrganizationId().trim()));
			userDao.save(u);
		}
	}

	public AdeUser get(String id) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);
		TadeUser t = userDao.get("select distinct t from TadeUser t left join fetch t.tadeRoles role where t.id = :id",
				params);
		AdeUser u = new AdeUser();
		BeanUtils.copyProperties(t, u);
		if (t.getTadeRoles() != null && !t.getTadeRoles().isEmpty()) {
			String roleIds = "";
			String roleNames = "";
			boolean b = false;
			for (TadeRole role : t.getTadeRoles()) {
				if (b) {
					roleIds += ",";
					roleNames += ",";
				} else {
					b = true;
				}
				roleIds += role.getId();
				roleNames += role.getRoleName();
			}

			u.setRoleIds(roleIds);
			u.setRoleNames(roleNames);
		}
		TadeOrganization org = t.getTadeOrganization();
		if (org != null && StringUtils.isNotBlank(org.getOrgName())) {
			u.setOrganizationId(org.getId());
			u.setOrganizationName(org.getOrgName());
		}
		return u;
	}

	synchronized public void edit(AdeUser user) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", user.getId());
		params.put("loginName", user.getLoginName());
		if (userDao.count("select count(*) from TadeUser t where t.loginName = :loginName and t.id != :id",
				params) > 0) {
			throw new Exception("登录名已存在！");
		} else {

			TadeUser u = userDao.get(TadeUser.class, user.getId());
			u.setTadeOrganization(organizationDao.get(TadeOrganization.class, user.getOrganizationId().trim()));

			BeanUtils.copyProperties(user, u, new String[] { "password", "createDate" });
			u.setNameLetter(ChineseCharToEn.getFristLetter(u.getUserName()));
			u.setUpdateDate(new Date());
			userDao.save(u);
		}
	}

	/**
	 * 删除用户：非物理删除，但是会删除与该用户相关的对象关联信息删除。比如（角色/组织机构）
	 * 
	 * @param id
	 */
	public void delete(String id) {

		TadeUser tuser = userDao.get(TadeUser.class, id);

		tuser.setTadeRoles(null);
		tuser.setTadeOrganization(null);
		tuser.setUserState(CodeConstant.STATE_FREEZE);
		userDao.update(tuser);
	}

	/**
	 * 还原用户
	 * 
	 * @param id
	 */
	public void recovery(String id) {
		TadeUser tuser = userDao.get(TadeUser.class, id);
		tuser.setUserState(CodeConstant.STATE_NORMAL);
		userDao.update(tuser);
	}

	/**
	 * 用户授权，需要参数为userId与roleIds两个参数
	 * 
	 * @param user
	 * @return
	 */
	public String grant(String userId, String roleIds) {

		TadeUser t = userDao.get(TadeUser.class, userId);

		List<TadeRole> roles = new ArrayList<TadeRole>();
		if (StringUtil.isNotEmpty(roleIds)) {
			for (String roleId : roleIds.split(",")) {
				roles.add(roleDao.get(TadeRole.class, roleId));
			}
			t.setTadeRoles(new HashSet<TadeRole>(roles));
		} else {
			t.setTadeRoles(null);
		}

		return null;
	}

	public List<String> moduleList(AdeUser user) {
		List<String> moduleList = new ArrayList<String>();
		if (user.getLoginName().equals(CodeConstant.SUPER_USER_LOGIN_NAME)) {
			List<TadeModule> list = moduleDao.find("from TadeModule");
			if (list != null && list.size() > 0) {
				for (TadeModule tadeModule : list) {
					moduleList.add(tadeModule.getModuleUrl());
				}
			}
		} else {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("id", user.getId());
			TadeUser t = userDao.get(
					"from TadeUser t join fetch t.tadeRoles role join fetch role.tadeModules module where t.id = :id",
					params);
			if (t != null) {
				Set<TadeRole> roles = t.getTadeRoles();
				if (roles != null && !roles.isEmpty()) {
					for (TadeRole role : roles) {
						Set<TadeModule> resources = role.getTadeModules();
						if (resources != null && !resources.isEmpty()) {
							for (TadeModule resource : resources) {
								if (resource != null && resource.getModuleUrl() != null) {
									moduleList.add(resource.getModuleUrl());
								}
							}
						}
					}
				}
			}
		}
		return moduleList;
	}

	public void editPwd(AdeUser user) {
		if (user != null && user.getPassword() != null && !user.getPassword().trim().equalsIgnoreCase("")) {
			TadeUser u = userDao.get(TadeUser.class, user.getId());
			u.setPassword(MD5Util.md5(user.getPassword()));
		}
	}

	public boolean editCurrentUserPwd(String userId, String oldPwd, String pwd) {
		TadeUser u = userDao.get(TadeUser.class, userId);
		if (u.getPassword().equalsIgnoreCase(MD5Util.md5(oldPwd))) {// 说明原密码输入正确
			u.setPassword(MD5Util.md5(pwd));
			return true;
		}
		return false;
	}

	public List<Long> userCreateDatetimeChart() {
		List<Long> l = new ArrayList<Long>();
		int k = 0;
		for (int i = 0; i < 12; i++) {
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("s", k);
			params.put("e", k + 2);
			k = k + 2;
			l.add(userDao.count(
					"select count(*) from TadeUser t where HOUR(t.createDate)>=:s and HOUR(t.createDate)<:e", params));
		}
		return l;
	}

	/**
	 * 根据用户登录名获取用户信息
	 * 
	 * @param loginName
	 * @return
	 */
	public AdeUser getUserByLoginName(String loginName) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("loginName", loginName);
		TadeUser t = userDao.get("from TadeUser t where t.loginName = :loginName ", params);
		AdeUser user = new AdeUser();
		if (t != null) {
			BeanUtils.copyProperties(t, user);
			if (t.getTadeRoles() != null && !t.getTadeRoles().isEmpty()) {
				String roleIds = "";
				String roleNames = "";
				boolean b = false;
				for (TadeRole role : t.getTadeRoles()) {
					if (b) {
						roleIds += ",";
						roleNames += ",";
					} else {
						b = true;
					}
					roleIds += role.getId();
					roleNames += role.getRoleName();
				}
				user.setRoleIds(roleIds);
				user.setRoleNames(roleNames);
			}
			return user;
		}
		return null;
	}

	public List<EasyUIComboTree> getuser() {

		String hql = " from TadeUser t";

		List<TadeUser> list = userDao.find(hql);
		List<EasyUIComboTree> liste = new ArrayList<EasyUIComboTree>();
		if (list != null && list.size() > 0) {
			for (TadeUser tuser : list) {
				EasyUIComboTree et = new EasyUIComboTree();
				et.setId(tuser.getId());
				et.setText(tuser.getLoginName());
				liste.add(et);
			}
		}
		return liste;
	}

	/**
	 * 导入Excel
	 * 
	 * @param excelFile
	 */
	public void saveExcelInfo(File excelFile) throws Exception {
		try {
			Workbook rb = new XSSFWorkbook(new FileInputStream(excelFile));
			Sheet sheet1 = rb.getSheetAt(0);
			if (sheet1 != null) {
				for (Row row : sheet1) {
					if (sheet1.getRow(0).equals(row)) {
						continue;
					}

					TadeUser u = new TadeUser();
					AdeUser user = new AdeUser();
					String loginName = ExcelUtil.getCellValue(row.getCell(0));
					user.setLoginName(loginName);
					String userName = ExcelUtil.getCellValue(row.getCell(1));
					user.setUserName(userName);
					String sex = ExcelUtil.getCellValue(row.getCell(2));
					user.setSex(sex);
					String mobilePhone = ExcelUtil.getCellValue(row.getCell(3));
					user.setMobilePhone(mobilePhone);
					String telePhone = ExcelUtil.getCellValue(row.getCell(4));
					user.setTelePhone(telePhone);
					String email = ExcelUtil.getCellValue(row.getCell(5));
					user.setEmail(email);
					String ip = ExcelUtil.getCellValue(row.getCell(6));
					user.setIp(ip);

					user.setPassword("123456");
					Map<String, Object> params = new HashMap<String, Object>();
					params.put("loginName", loginName);
					TadeUser tUser = userDao.get("from TadeUser t where t.loginName = :loginName", params);
					if (tUser != null) {
						tUser.setUserName(user.getUserName());
						tUser.setSex(user.getSex());
						tUser.setMobilePhone(user.getMobilePhone());
						tUser.setTelePhone(user.getTelePhone());
						tUser.setEmail(user.getEmail());
						tUser.setIp(user.getIp());
						// 获取最高级部门
						String cellValue = ExcelUtil.getCellValue(row.getCell(7));
						// 对导入的组织名称进行查询,不存在就保存
						if (!StringUtils.isBlank(cellValue)) {
							String[] orgArr = cellValue.split("/");
							// =====
							String pOrgid = updateOrganization(orgArr, 0, "");
							if (StringUtils.isNotBlank(pOrgid)) {
								tUser.setTadeOrganization(organizationDao.get(TadeOrganization.class, pOrgid.trim()));
							}
						}

						tUser.setCreateDate(new Date());

						// tUser.setUserState(CodeConstant.USER_STATE_NORMAL);
						tUser.setNameLetter(ChineseCharToEn.getFristLetter(user.getUserName()));
						// u.setTorganization(organizationDao.get(Torganization.class,
						// user.getOrganizationId().trim()));
						userDao.save(tUser);
						continue;
					}

					// 获取最高级部门
					String cellValue = ExcelUtil.getCellValue(row.getCell(7));
					// 对导入的组织名称进行查询,不存在就保存
					if (!StringUtils.isBlank(cellValue)) {
						String[] orgArr = cellValue.split("/");
						// =====
						String pOrgid = updateOrganization(orgArr, 0, "");
						if (StringUtils.isNotBlank(pOrgid)) {
							u.setTadeOrganization(organizationDao.get(TadeOrganization.class, pOrgid.trim()));
						}
					}

					// 保存用户
					BeanUtils.copyProperties(user, u);
					u.setId(StringUtil.generateUUID());
					u.setPassword(MD5Util.md5(user.getPassword()));
					u.setCreateDate(new Date());

					u.setUserState(CodeConstant.STATE_NORMAL);
					u.setNameLetter(ChineseCharToEn.getFristLetter(u.getUserName()));
					// u.setTorganization(organizationDao.get(Torganization.class,
					// user.getOrganizationId().trim()));
					userDao.save(u);

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * orgArr数组 n下标and t.torganization.id=:id 顶级目录集合
	 */
	public String updateOrganization(String[] orgArr, int n, String pid) {
		TadeOrganization torganization = new TadeOrganization();
		String orgName = orgArr[n];
		TadeOrganization torganization2 = new TadeOrganization();
		TadeOrganization torganization3 = new TadeOrganization();
		if (n == 0) {
			String hql = "from TadeOrganization t where t.orgName=:orgName ";
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("orgName", orgName);
			// params.put("id", pid);
			torganization2 = organizationDao.get(hql, params);
			if (torganization2 == null) {
				torganization.setId(StringUtil.generateUUID());
				torganization.setOrgName(orgName);
				torganization.setOrgStatus(CodeConstant.STATE_NORMAL);
				organizationDao.save(torganization);
				torganization3.setId(torganization.getId());
			} else {
				torganization3.setId(torganization2.getId());
			}
		} else {
			String hql = "from TadeOrganization t where t.orgName=:orgName and t.tadeOrganization.id=:id";
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("orgName", orgName);
			params.put("id", pid);
			torganization2 = organizationDao.get(hql, params);
			if (torganization2 == null) {
				torganization.setId(StringUtil.generateUUID());
				torganization.setOrgName(orgName);
				torganization.setTadeOrganization(organizationDao.get(TadeOrganization.class, pid));
				torganization.setOrgStatus(CodeConstant.STATE_NORMAL);
				organizationDao.save(torganization);
				torganization3.setId(torganization.getId());
			} else {
				torganization3.setId(torganization2.getId());
			}
		}

		if ((orgArr.length - 1) == n) {
			return torganization3.getId();
		} else {
			return updateOrganization(orgArr, n + 1, torganization3.getId());
		}
	}
}
